import os
import requests
from difflib import SequenceMatcher
from docx import Document
import argparse
import tempfile
import shutil
import subprocess
from collections import defaultdict


def clone_repository(repo_url, target_dir):
    """克隆仓库到临时目录"""
    if os.path.exists(target_dir):
        shutil.rmtree(target_dir)
    subprocess.run(['git', 'clone', '--bare', repo_url, target_dir], check=True)


def get_branches(repo_dir):
    """获取所有分支列表"""
    result = subprocess.run(['git', '-C', repo_dir, 'branch', '-a'],
                            stdout=subprocess.PIPE, text=True, check=True)
    branches = [b.strip('* ').strip() for b in result.stdout.split('\n') if b]
    # 过滤掉远程分支的remotes/origin/前缀
    return [b.replace('remotes/origin/', '') for b in branches if 'HEAD' not in b]


def checkout_branch(repo_dir, branch, work_dir):
    """检出特定分支到工作目录"""
    if os.path.exists(work_dir):
        shutil.rmtree(work_dir)
    os.makedirs(work_dir)
    subprocess.run(['git', '-C', repo_dir, 'worktree', 'add', work_dir, branch], check=True)


def extract_text_from_docx(docx_path):
    """从Word文档中提取文本"""
    try:
        doc = Document(docx_path)
        return '\n'.join([para.text for para in doc.paragraphs])
    except:
        return ""


def find_docx_files(directory):
    """查找目录中的所有Word文档"""
    docx_files = []
    for root, _, files in os.walk(directory):
        for file in files:
            if file.lower().endswith('.docx'):
                docx_files.append(os.path.join(root, file))
    return docx_files


def calculate_similarity(text1, text2):
    """计算两个文本的相似度"""
    return SequenceMatcher(None, text1, text2).ratio()


def compare_branches(repo_dir, branches, similarity_threshold=0.8):
    """比较不同分支中的Word文档相似度"""
    results = defaultdict(dict)

    with tempfile.TemporaryDirectory() as temp_dir:
        for branch in branches:
            branch_work_dir = os.path.join(temp_dir, branch)
            checkout_branch(repo_dir, branch, branch_work_dir)

            docx_files = find_docx_files(branch_work_dir)
            for docx_file in docx_files:
                relative_path = os.path.relpath(docx_file, branch_work_dir)
                text = extract_text_from_docx(docx_file)
                results[relative_path][branch] = text

    # 比较相同路径下的文档内容
    report = []
    for file_path, branch_texts in results.items():
        if len(branch_texts) < 2:
            continue

        branches = list(branch_texts.keys())
        for i in range(len(branches)):
            for j in range(i + 1, len(branches)):
                branch1 = branches[i]
                branch2 = branches[j]
                text1 = branch_texts[branch1]
                text2 = branch_texts[branch2]
                similarity = calculate_similarity(text1, text2)

                if similarity >= similarity_threshold:
                    report.append({
                        'file': file_path,
                        'branch1': branch1,
                        'branch2': branch2,
                        'similarity': similarity
                    })

    return report


def main():
    parser = argparse.ArgumentParser(description='Gitee仓库Word文档查重工具')
    parser.add_argument('repo_url', help='Gitee仓库URL')
    parser.add_argument('--threshold', type=float, default=0.8,
                        help='相似度阈值(0-1), 默认0.8')
    args = parser.parse_args()

    # 创建临时目录
    with tempfile.TemporaryDirectory() as temp_dir:
        repo_dir = os.path.join(temp_dir, 'repo.git')

        print(f"正在克隆仓库 {args.repo_url}...")
        clone_repository(args.repo_url, repo_dir)

        print("获取分支列表...")
        branches = get_branches(repo_dir)
        print(f"找到分支: {', '.join(branches)}")

        print("开始比较Word文档内容...")
        report = compare_branches(repo_dir, branches, args.threshold)

        print("\n查重结果:")
        if not report:
            print("没有找到高度相似的Word文档")
        else:
            for item in report:
                print(f"文件: {item['file']}")
                print(f"分支: {item['branch1']} 与 {item['branch2']}")
                print(f"相似度: {item['similarity']:.2%}")
                print("-" * 50)


if __name__ == '__main__':
    main()